/* -*-mode:c++; coding:utf-8 */

/* 参考自ACE中Atomic_Op的实现 */

#ifndef _XBASE_ATOMIC_ADAPTER_HPP_
#define _XBASE_ATOMIC_ADAPTER_HPP_

#include <boost/thread/thread.hpp>

namespace xbase 
{

	template <typename Integer>
	class atomic_adapter {
	public:
		typedef Integer value_type;

	private:
		typedef atomic_adapter<Integer> this_type;
	
	public:
		/// Initialize @c value_ to 0.
		atomic_adapter ()
			: m_value(0) {}

		/// Initialize @c value_ to c.
		atomic_adapter (const value_type p_value)
			: m_value(p_value) {}

		/// Manage copying...
		atomic_adapter (const this_type &rhs)
			: m_value(rhs.value()) {}
	
		/// Atomically assign rhs to @c value_.
		this_type &operator= (const value_type rhs) {
			boost::mutex::scoped_lock guard(m_mutex);
			m_value = rhs;
			return *this;
		}

		/// Atomically assign <rhs> to @c value_.
		this_type &operator= (const this_type &rhs) {
			if(this != &rhs)
			{
				boost::mutex::scoped_lock guard(m_mutex);
				m_value = rhs.value();
			}
			return *this;
		}

		/// Atomically pre-increment @c value_.
		value_type operator++ (void) {
			boost::mutex::scoped_lock guard(m_mutex);
			return ++m_value;
		}

		/// Atomically post-increment @c value_.
		value_type operator++ (int) {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value++;
		}

		/// Atomically increment @c value_ by rhs.
		value_type operator+= (const value_type rhs) {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value += rhs;
		}

		/// Atomically pre-decrement @c value_.
		value_type operator-- () {
			boost::mutex::scoped_lock guard(m_mutex);
			return --m_value;
		}

		/// Atomically post-decrement @c value_.
		value_type operator-- (int) {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value--;
		}

		/// Atomically decrement @c value_ by rhs.
		value_type operator-= (const value_type rhs) {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value -= rhs;
		}

		/// Atomically compare @c value_ with rhs.
		bool operator== (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value == rhs;
		}

		/// Atomically compare @c value_ with rhs.
		bool operator!= (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value != rhs;
		}

		/// Atomically check if @c value_ greater than or equal to rhs.
		bool operator>= (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value >= rhs;
		}

		/// Atomically check if @c value_ greater than rhs.
		bool operator> (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value > rhs;
		}

		/// Atomically check if @c value_ less than or equal to rhs.
		bool operator<= (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value <= rhs;
		}

		/// Atomically check if @c value_ less than rhs.
		bool operator< (const value_type rhs) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value < rhs;
		}

		/// Explicitly return @c value_.
		value_type value (void) const {
			boost::mutex::scoped_lock guard(m_mutex);
			return m_value;
		}

		// 如果Pred(当前值,给定值)返回True，则更新为给定值；否
		// 则不变。如果设置了，则返回True，否则返回False，即返
		// 回Pred的结果。
		template<typename Pred>
		bool assign_if(const value_type value,
			       Pred pred) {
			boost::mutex::scoped_lock guard(m_mutex);
			const bool ret = pred(m_value, value);
			if(ret)
			{
				m_value = value;
			}
			return ret;
		}

		// 如果Pred(当前值,给定值)返回True，则更新为给定值；否
		// 则不变。如果设置了，则返回True，否则返回False，即返
		// 回Pred的结果。
		bool assign_if(const value_type value,
			       const value_type pred) {
			boost::mutex::scoped_lock guard(m_mutex);
			const bool ret = (m_value == pred);
			if(ret)
			{
				m_value = value;
			}
			return ret;
		}

	private:
		value_type m_value;
		mutable boost::mutex m_mutex;
	};
	
} // namespace xbase

#endif	// _XBASE_ATOMIC_ADAPTER_HPP_
